﻿using Conference.Command.Command;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Conference.Common.Log;
using DotNetCore.CAP;
using Conference.Domain.Entity;
using Conference.Domain;
using Conference.Domain.Repository;
using Exceptionless;
using Conference.Common;

namespace Conference.CommandHandler
{
    /// <summary>
    /// 会议CommandHandler
    /// </summary>
    public class ConferenceCommandHandler :
        IConferenceCommandHandler,
        ICapSubscribe,
        ICommandHandler<CreateCustomerCommand>,
        ICommandHandler<CreateConferenceCommand>,
        ICommandHandler<AddSeatTypeCommand>,
        ICommandHandler<PublishConferenceCommand>
    {
        private readonly IPublishDomainEventService _publishDomainEvent;
        private readonly IConferenceRepository _conferenceRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly ILoggerHelper _loggerHelper;

        public ConferenceCommandHandler(IPublishDomainEventService publishDomainEvent, IConferenceRepository conferenceRepository,
            IUnitOfWork unitOfWork, ICustomerRepository customerRepository, ILoggerHelper loggerHelper)
        {
            _publishDomainEvent = publishDomainEvent;
            _conferenceRepository = conferenceRepository;
            _unitOfWork = unitOfWork;
            _customerRepository = customerRepository;
            _loggerHelper = loggerHelper;
        }

        /// <summary>
        /// 创建会议命令
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [CapSubscribe(nameof(CreateConferenceCommand), Group = nameof(CreateConferenceCommand))]
        public async Task HandleAsync(CreateConferenceCommand command)
        {
            try
            {
                var conference = new ConferenceInfo(command.AggregateRootId);
                conference.CreateConference(command.ConferenceName, command.ConferenceContent, command.ConferenceAddress, command.ConferenceParticipantNum, command.ConferenceStartTime, command.ConferenceEndTime, command.CustomerId);
                AggregateRootRepository.AddAsync(conference);
                await Task.Factory.StartNew(async () =>
                {
                    await _publishDomainEvent.AppendEventStoragePublishEventAsync(conference).ConfigureAwait(false);
                });
            }
            catch (Exception e)
            {
                e.ToExceptionless().Submit();
                throw;
            }
        }

        /// <summary>
        /// 添加座位类型
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [CapSubscribe(nameof(AddSeatTypeCommand), Group = nameof(AddSeatTypeCommand))]
        public async Task HandleAsync(AddSeatTypeCommand command)
        {
            //获取聚合根的状态
            var conference = await _conferenceRepository.GetConference(command.AggregateRootId);
            List<SeatType> seatTypeList = new List<SeatType>();
            var seatType = new SeatType("舒适型", 60, 20, command.AggregateRootId);
            seatTypeList.Add(seatType);
            conference.AddSeatType(seatTypeList);
            //await _publishDomainEvent.PublishEventAsync(conference);
        }

        /// <summary>
        /// 发布会议
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [CapSubscribe(nameof(PublishConferenceCommand), Group = nameof(PublishConferenceCommand))]
        public async Task HandleAsync(PublishConferenceCommand command)
        {
            //var conference = await _conferenceRepository.GetConference(command.AggregateRootId);
            //conference.PublishConference();
            //await Task.Factory.StartNew(async () =>
            //{
            //    await _publishDomainEvent.AppendEventStoragePublishEventAsync(conference).ConfigureAwait(false);
            //});
            //var conference = new ConferenceInfo(command.AggregateRootId);
            //EventStorageRepository aggregateRootEventStorageRepository = new EventStorageRepository();
            //var domainEventList = await aggregateRootEventStorageRepository.GetAggregateRootEventStorageById(command.AggregateRootId).ConfigureAwait(false);
            //conference.ReplayEvent(domainEventList);
            var conference =await AggregateRootRepository.GetAsync<ConferenceInfo>(command.AggregateRootId.ToString());
            conference.PublishConference();
        }

        /// <summary>
        /// 创建客户
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [CapSubscribe(nameof(CreateCustomerCommand), Group = nameof(CreateCustomerCommand))]
        public async Task HandleAsync(CreateCustomerCommand command)
        {
            try
            {
                var customer = new Customer(command.AggregateRootId);
                customer.CreateCustomer(command.CustomerName, command.CustomerAge, command.CustomerPhone,
                    command.CustomerAddress.Province, command.CustomerAddress.City, command.CustomerAddress.County,
                    command.CustomerAddress.AddressDetails);
                await _customerRepository.AddCustomer(customer);
                await _unitOfWork.CommitAsync();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
    }
}
